package cn.iocoder.yudao.module.distm.service.schedule;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.distm.controller.admin.schedule.vo.FlightLogImportRespVO;
import cn.iocoder.yudao.module.distm.controller.admin.schedule.vo.ScheduleRecordPageReqVO;
import cn.iocoder.yudao.module.distm.controller.admin.schedule.vo.ScheduleRecordSaveReqVO;
import cn.iocoder.yudao.module.distm.controller.app.schedulerecord.vo.AppDeliveryPageReqVO;
import cn.iocoder.yudao.module.distm.controller.app.schedulerecord.vo.AppScheduleRecordPageReqVO;
import cn.iocoder.yudao.module.distm.controller.app.schedulerecord.vo.AppScheduleRecordSaveReqVO;
import cn.iocoder.yudao.module.distm.dal.dataobject.quarterplan.QuarterPlanDO;
import cn.iocoder.yudao.module.distm.dal.dataobject.schedule.ScheduleRecordDO;
import cn.iocoder.yudao.module.distm.dal.dataobject.schedule.ScheduleRecordHistoryDO;
import cn.iocoder.yudao.module.distm.dal.mysql.quarterplan.QuarterPlanMapper;
import cn.iocoder.yudao.module.distm.dal.mysql.schedule.ScheduleRecordHistoryMapper;
import cn.iocoder.yudao.module.distm.dal.mysql.schedule.ScheduleRecordMapper;
import cn.iocoder.yudao.module.distm.utils.FlightLogUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.distm.enums.ErrorCodeConstants.SCHEDULE_RECORD_NOT_EXISTS;

/**
 * 配送管理-调度生产记录 Service 实现类
 *
 * @author yisl
 */
@Service
@Validated
public class ScheduleRecordServiceImpl implements ScheduleRecordService {

    @Resource
    private ScheduleRecordMapper scheduleRecordMapper;
    @Resource
    private QuarterPlanMapper quarterPlanMapper;

    @Resource
    private ScheduleRecordHistoryMapper scheduleRecordHistoryMapper;

    @Override
    public Long createScheduleRecord(ScheduleRecordSaveReqVO createReqVO) {
        // 插入
        ScheduleRecordDO scheduleRecord = BeanUtils.toBean(createReqVO, ScheduleRecordDO.class);
        scheduleRecordMapper.insert(scheduleRecord);
        // 返回
        return scheduleRecord.getId();
    }

    @Override
    public void updateScheduleRecord(ScheduleRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateScheduleRecordExists(updateReqVO.getId());
        // 更新
        ScheduleRecordDO updateObj = BeanUtils.toBean(updateReqVO, ScheduleRecordDO.class);
        scheduleRecordMapper.updateById(updateObj);
    }

    @Override
    public void deleteScheduleRecord(Long id) {
        // 校验存在
        validateScheduleRecordExists(id);
        // 删除
        scheduleRecordMapper.deleteById(id);
    }

    @Override
        public void deleteScheduleRecordListByIds(List<Long> ids) {
        // 校验存在
        validateScheduleRecordExists(ids);
        // 删除
        scheduleRecordMapper.deleteByIds(ids);
        }

    private void validateScheduleRecordExists(List<Long> ids) {
        List<ScheduleRecordDO> list = scheduleRecordMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(SCHEDULE_RECORD_NOT_EXISTS);
        }
    }

    private void validateScheduleRecordExists(Long id) {
        if (scheduleRecordMapper.selectById(id) == null) {
            throw exception(SCHEDULE_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public ScheduleRecordDO getScheduleRecord(Long id) {
        return scheduleRecordMapper.selectById(id);
    }

    @Override
    public PageResult<ScheduleRecordDO> getScheduleRecordPage(ScheduleRecordPageReqVO pageReqVO) {
        return scheduleRecordMapper.selectPage(pageReqVO);
    }

    @Override
    public void syncQuarterPlan() {
        // 获取当前班期--星期几
        String locPat = LocalDate.now().getDayOfWeek().getValue()+"";
        // 从distm_quarter_plan 中查询sch_patb包含当前班期的列表,
        // 目前数据量只有300多条，未考虑分页查询
        List<QuarterPlanDO> quarterPlanDOS = quarterPlanMapper.selectList(new LambdaQueryWrapperX<QuarterPlanDO>()
                .likeIfPresent(QuarterPlanDO::getSchPat, locPat));
        if (CollUtil.isEmpty(quarterPlanDOS)) {
            return;
        }
        List<ScheduleRecordDO> scheduleRecordDOS = new ArrayList<>(quarterPlanDOS.size());
        quarterPlanDOS.forEach(quarterPlan -> {
            ScheduleRecordDO createObj = BeanUtils.toBean(quarterPlan, ScheduleRecordDO.class);
            createObj.setId(null).setCreator(null).setCreateTime(null).setUpdater(null).setUpdateTime(null);
            createObj.setRecordDate(LocalDate.now());
            scheduleRecordDOS.add(createObj);
        });
        scheduleRecordMapper.insertBatch(scheduleRecordDOS);
    }

    @Override
    public FlightLogImportRespVO flightLogImport(byte[] content, boolean isUpdateSupport) {

        String input = new String(content);
        Pattern pattern = Pattern.compile("REQ MEAL\\s+(.*?)\\s+END", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(input);

        List<ScheduleRecordDO> scheduleRecordDOS = new ArrayList<>();
        String recordDate = FlightLogUtils.formatFlightDate();
        while (matcher.find()) {
            if (matcher.group(1).contains(recordDate)){
                ScheduleRecordDO scheduleRecordDO = new ScheduleRecordDO();
                FlightLogUtils.extractFlightMealData(matcher.group(1), scheduleRecordDO);
                scheduleRecordDOS.add(scheduleRecordDO);
            }
        }

        // 去重-保留最后解析的数据
        List<ScheduleRecordDO> distinctRecords = new ArrayList<>(
                scheduleRecordDOS.stream().collect(Collectors.toMap(record -> Arrays.asList(record.getId(), record.getFlightNo()),
                        record -> record, (oldVal, newVal) -> newVal
                        )).values());
        AtomicInteger count = new AtomicInteger();
        distinctRecords.forEach(record -> count.addAndGet(scheduleRecordMapper.update(record, new LambdaQueryWrapperX<ScheduleRecordDO>().eq(ScheduleRecordDO::getFlightNo, record.getFlightNo()))));

        FlightLogImportRespVO respVO = FlightLogImportRespVO.builder().createLogs("").build();
        respVO.setCreateLogs(String.valueOf(distinctRecords.size()));
        respVO.setUpdateLogs(count.toString());
        return respVO;
    }

    @Override
    public void appUpdateScheduleRecord(AppScheduleRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateScheduleRecordExists(updateReqVO.getId());
        // 更新
        ScheduleRecordDO updateObj = BeanUtils.toBean(updateReqVO, ScheduleRecordDO.class);
        scheduleRecordMapper.updateById(updateObj);
    }

    @Override
    public ScheduleRecordDO appGetScheduleRecord(Long id) {
        return scheduleRecordMapper.selectById(id);
    }

    @Override
    public PageResult<ScheduleRecordDO> appGetScheduleRecordPage(AppScheduleRecordPageReqVO pageReqVO) {
        return scheduleRecordMapper.appSelectPage(pageReqVO);
    }

    @Override
    public PageResult<ScheduleRecordDO> appTodayScheduleRecordPage(AppDeliveryPageReqVO pageReqVO) {
        Long userId = getLoginUserId();
        pageReqVO.setUserId("["+userId+"]");
        return scheduleRecordMapper.appTodaySelectPage(pageReqVO);
    }

    @Override
    public PageResult<ScheduleRecordHistoryDO> appHistoryScheduleRecordPage(AppDeliveryPageReqVO pageReqVO) {
        Long userId = getLoginUserId();
        pageReqVO.setUserId("["+userId+"]");
        return scheduleRecordHistoryMapper.appHistorySelectPage(pageReqVO);
    }

}